package com.gomcarter.frameworks.base.cross;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.ObjectUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 跨域配置
 * @author z.y.h
 * create on 2023/3/3 12:06
 */
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CrossAccessFilter extends OncePerRequestFilter {
    private static final String OPTIONS_METHOD = "OPTIONS";
    private static final String ORIGIN_HEADER = "Origin";
    private static final String ACCESS_CONTROL_ALLOW_METHODS = "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE";
    private static final String ACCESS_CONTROL_ALLOW_HEADERS = "Origin, X-Requested-With, Content-Type, Accept, Set-Cookie, " +
            "sw8, token, x-app-id, x-security-type";
    private final String appendAllowHeaders;

    public CrossAccessFilter(String appendAllowHeaders) {
        this.appendAllowHeaders = appendAllowHeaders;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String allowHeaders = ObjectUtils.isEmpty(appendAllowHeaders) ? ACCESS_CONTROL_ALLOW_HEADERS : ACCESS_CONTROL_ALLOW_HEADERS + "," + appendAllowHeaders;
        String origin = request.getHeader(ORIGIN_HEADER);
        if (origin == null || "null".equalsIgnoreCase(origin)) {
            response.setHeader("Access-Control-Allow-Origin", "*");
        } else {
            response.setHeader("Access-Control-Allow-Origin", origin);
            response.setHeader("Access-Control-Allow-Credentials", Boolean.TRUE.toString());
        }
        response.setHeader("Access-Control-Allow-Methods", ACCESS_CONTROL_ALLOW_METHODS);
        response.setHeader("Access-Control-Allow-Headers", allowHeaders);
        if (!OPTIONS_METHOD.equals(request.getMethod())) {
            filterChain.doFilter(request, response);
        }
    }
}
